home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / linkedit / linkedit.lha / link-edit / LinkEdit / Choose / choose.c.old < prev    next >
Encoding:
Text File  |  1991-03-13  |  13.3 KB  |  437 lines

  1. #include <X11/Xlib.h>
  2. #include <X11/Xutil.h>
  3. #include <X11/cursorfont.h>
  4. #include <stdio.h>
  5. #include <sys/types.h>
  6. #include <dirent.h>
  7. #include <malloc.h>
  8.  
  9. #define MaxFiles 100
  10. #define MaxName 100
  11. #define MaxSuff 100
  12. #define mystuff mydisplay, mywindow, mygc
  13. #define rmystuff mydisplay, mywindow, rmygc
  14. #define font "9x15"   /* 9x15 */
  15. #define min(A,B) ((A>=B) ? B : A)
  16. #define max(A,B) ((A>=B) ? A : B)
  17. #define message(A); XFillRectangles(mystuff,&messbox,1); \
  18.   XDrawString(rmystuff,messbox.x+5,messbox.y+letheight, A, strlen(A));
  19. static XSizeHints myhint;
  20. static shwdir=1;
  21. static char *sufv[MaxSuff]; 
  22. static int sufc=0;
  23. static XFontStruct *font_struct;
  24. static int letwidth=6;
  25. static int letheight=13;
  26. static int rows=10;
  27. static XRectangle lstbox,cancelbox,okbox,fnamebox,upbox,downbox,mvbox,messbox;
  28. static char *prompt_string="file name: ";  
  29. struct elm {
  30.   int chose;
  31.   int ftype;
  32.   char name[MaxName];
  33. };
  34.  
  35. /*** TOBY addition */
  36. extern Display *dpy;
  37.  
  38. int
  39. showdir(which)
  40.   int which;
  41. {  shwdir=which; return(which); }
  42.  
  43. int
  44. addsuff(name)
  45.   char *name;
  46. { if (sufc<MaxSuff)
  47.   { sufc++;
  48.     *(sufv+sufc-1)=(char *)malloc((strlen(name)+2)*sizeof(char));
  49.     strcpy(*(sufv+sufc-1),name); return(1);
  50.   }
  51.   else return(0);
  52. }
  53.  
  54. int
  55. clearsuff()
  56. { int t;
  57.   for(t=0; t<sufc; t++) free(*(sufv+t));
  58.   sufc=0;
  59. }
  60. int
  61. delsuff(name)
  62.   char *name;
  63. { int t,t2,good=0;
  64.   for(t=0; t<sufc; t++)
  65.     if (strcmp(name,*(sufv+t))==0)
  66.     { free(*(sufv+t)); 
  67.       good=1;
  68.       for(t2=t; t2<sufc; t2++) *(sufv+t2) = *(sufv+t2+1);
  69.       t--;
  70.       sufc--;
  71.     }
  72.    return(good);
  73. }
  74.  
  75. int
  76. suflist(name)
  77.   char *name;
  78. { int t;
  79.   if (sufc==0) return(1);
  80.   for(t=0; t<sufc; t++)
  81.     if (match(name,*(sufv+t)))  return(1);
  82.   return(0);
  83. }
  84.   
  85. void
  86. chfree(namesc, namesv)
  87.   int *namesc;
  88.   char ***namesv;
  89.   while ((*namesc)-->0)
  90.     if (*((*namesv)+(*namesc))!=NULL) free(*((*namesv)+(*namesc)));
  91.   if (*namesv!=NULL) free(*namesv);
  92. }
  93.  
  94. XRectangle assign(x,y,width,height)
  95.   int x,y,width,height;
  96. { XRectangle box;
  97.   box.x=x;
  98.   box.y=y;
  99.   box.width=width;
  100.   box.height=height;
  101.   return(box);
  102. }
  103.  
  104. void init2()
  105. { lstbox=assign(19,19,15*letwidth+4,rows*letheight+4);
  106.   upbox=assign(lstbox.x+lstbox.width,lstbox.y,15,15);
  107.   downbox=assign(upbox.x,lstbox.y+lstbox.height-15,15,15);
  108.   mvbox=assign(upbox.x,upbox.y+upbox.height,15,downbox.y-upbox.y-upbox.height);
  109.   fnamebox=assign(0,lstbox.y+lstbox.height+30,letwidth*45+4,letheight*3+4);
  110.   okbox=assign(upbox.x+upbox.width+50,50,letwidth*6+4,letheight+8);
  111.   cancelbox=assign(okbox.x,okbox.y+okbox.height+30,okbox.width,okbox.height);
  112.   messbox=assign(0,fnamebox.y+fnamebox.height+2,fnamebox.width,letheight+4);
  113. }
  114.  
  115. void init()
  116. { int ascent,descent,dummy;  
  117.   XCharStruct overall;
  118.   if (font_struct!=NULL) 
  119.   { XTextExtents(font_struct," ",1,&dummy,&ascent,&descent,&overall);
  120.     letwidth=overall.width;
  121.     letheight=ascent+descent;
  122.   }
  123.   init2();
  124.   myhint.width=fnamebox.x+fnamebox.width+4; myhint.height=messbox.y+messbox.height+4;
  125. }
  126.  
  127. inbox(box,myevent)
  128.   XRectangle box;
  129.   XEvent myevent;
  130. { if ( myevent.xbutton.x>=box.x && myevent.xbutton.x<=(box.x+box.width) &&
  131.     myevent.xbutton.y>=box.y && myevent.xbutton.y<=(box.y+box.height)) return(1);
  132.   else return(0);
  133. }
  134.  
  135. void Cleanlst(lst,dirl)
  136.   struct elm *lst;
  137.   int dirl;
  138. { int i;
  139.   for(i=1; i<=dirl; i++) lst[i].chose=0;
  140. }
  141.  
  142. void flash(mydisplay,mywindow,mygc,box)
  143.   Display *mydisplay; 
  144.   Window mywindow;
  145.   GC mygc;
  146.   XRectangle box;
  147. { int delay=200;
  148.   XEvent event;
  149.   XSetFunction(mydisplay,mygc,GXxor);
  150.   XFillRectangles(mystuff,&box,1);
  151.   XPeekEvent(mydisplay,&event); 
  152.   XFillRectangles(mystuff,&box,1); 
  153.   XSetFunction(mydisplay,mygc,GXcopy);
  154.  
  155. choosefile(namesc,namesv,dpath,dr,write_read)
  156.   int *namesc;
  157.   char ***namesv;
  158.   char **dpath;
  159.   char *dr;
  160.   int write_read;
  161. { FILE  *fp;
  162.   DIR *dirp,*dumdir; 
  163.   char dum[300] ,inp[MaxName+20],  dum2[300],shell[300], dum3[MaxName+20],
  164.     text[10],inp_string[30],chrctr[2]; 
  165.   int i,found,chrows,k=0,flag=1,ch,dirl,kold,smooth=0,rdraw=0,chgdir=0,moved=0,
  166.     done=0,getting=0,myscreen,x,y,pstn,start=1,n;
  167.   struct dirent *dp;
  168.   struct elm *lst;
  169.   Display *mydisplay;
  170.   Window mywindow,UrgWindow;
  171.   XWindowAttributes sizeatt;
  172.   GC mygc,rmygc;
  173.   XEvent event,myevent;
  174.   KeySym mykey;
  175.   Cursor curs1,curs2;
  176.   unsigned long myforeground, mybackground;
  177.   strcpy(inp_string,"");
  178.   strcpy(dum2,dr);
  179.   lst=(struct elm *)(malloc(MaxFiles*sizeof(struct elm)));
  180. /*******
  181.   mydisplay=XOpenDisplay("");
  182. *******/
  183.   mydisplay = dpy;  /* TOBY change */
  184.  
  185.   myscreen = DefaultScreen(mydisplay);
  186.   mybackground= WhitePixel(mydisplay,myscreen);
  187.   myforeground= BlackPixel(mydisplay,myscreen);
  188.   font_struct=XLoadQueryFont(mydisplay,font);
  189.   init();
  190.   myhint.flags =PPosition | PSize; 
  191.   mywindow=XCreateSimpleWindow (mydisplay, DefaultRootWindow (mydisplay), myhint.x,
  192.     myhint.y, myhint.width, myhint.height,5,myforeground,mybackground);
  193.   XSetStandardProperties(mydisplay,mywindow,(write_read) ? "Save" :
  194.     "Load" ,"choosefile",None,NULL,0, &myhint);
  195.   mygc=XCreateGC(mydisplay,mywindow,0,0);
  196.   rmygc=XCreateGC(mydisplay,mywindow,0,0);
  197.   if (font_struct!=NULL)  
  198.   { XSetFont(mydisplay,mygc,font_struct->fid);
  199.     XSetFont(mydisplay,rmygc,font_struct->fid);
  200.   }
  201.   curs1=XCreateFontCursor(mydisplay,XC_top_left_arrow);
  202.   curs2=XCreateFontCursor(mydisplay,XC_watch);
  203.   XDefineCursor(mydisplay,mywindow,curs1);
  204.   XSetBackground(mydisplay,mygc,mybackground);
  205.   XSetForeground(mydisplay,mygc,myforeground);
  206.   XSetBackground(mydisplay,rmygc,myforeground);
  207.   XSetForeground(mydisplay,rmygc,mybackground);
  208.   XSelectInput(mydisplay,mywindow,ButtonPressMask | PointerMotionMask | 
  209.     ButtonReleaseMask | KeyPressMask | ExposureMask );
  210.   XMapRaised(mydisplay,mywindow);
  211.   while (done ==0)  
  212.   { if (flag) 
  213.     { XDefineCursor(mydisplay,mywindow,curs2); 
  214.       message("");
  215.       dirl=0;
  216.       sprintf(shell,"cd %s; pwd",dum2);
  217.       fp=popen(shell,"r");
  218.       fgets(dum2,100,fp);     
  219.       pclose(fp); 
  220.       n=strlen(dum2);
  221.       if (n>0 && dum2[n-1]=='\n') dum2[n-1]='\0';
  222.       dirp=opendir(dum2);
  223.       if (dirp!=NULL) 
  224.       { for (dp=readdir(dirp); dp!=NULL; dp=readdir(dirp))
  225.         { if (dirl<(MaxFiles-1))
  226.           { strncpy((lst[++dirl].name),(dp->d_name),MaxName-1);
  227.             if (strlen(dp->d_name)>=MaxName)
  228.             { message("Some File Names are too long ");}
  229.             strcpy(dum,dum2);
  230.             strcat(dum,"/");
  231.             lst[dirl].chose=0;
  232.             lst[dirl].ftype=!((dumdir=opendir(strcat(dum,lst[dirl].name)))==NULL);
  233.             if (lst[dirl].ftype) closedir(dumdir);
  234.             if (!((lst[dirl].ftype && shwdir) ||
  235.               (suflist(dp->d_name) && !(lst[dirl].ftype) ))) dirl--;
  236.           }
  237.           else {message("Too many files in the Directory"); }
  238.         } 
  239.         closedir(dirp);
  240.       }
  241.       flag=0;
  242.       XDefineCursor(mydisplay,mywindow,curs1); 
  243.     }
  244.     if ((start) && (*namesc>0))
  245.     { for(start=0;*namesc>0; (*namesc)--)
  246.       { found=0;
  247.         for(i=dirl; i>=1; i--)
  248.           if (match(lst[i].name,*((*namesv)+(*namesc)-1)) && (!lst[i].ftype)) 
  249.           { lst[i].chose=1; found=1; k=i-2;  k=max(min(dirl+2-rows,k),0);
  250.             if (write_read) {i=0;*namesc=0;} 
  251.           }
  252.         if (found) strcpy(inp_string,*((*namesv)));
  253.       }
  254.     }
  255.     if (rdraw) 
  256.     { rdraw=0;
  257.       XDrawImageString (mystuff,okbox.x+(okbox.width)/2-letwidth*2,
  258.         okbox.y+okbox.height/2+letheight/2,(chgdir) ? "OPEN" : " OK ",4);
  259.       for(i=1; i<=rows && (i+k)<=dirl; i++)
  260.         if (lst[i+k].chose) 
  261.         { XFillRectangle(mystuff,lstbox.x+1,lstbox.y+3+(i-1)*letheight,
  262.             15*letwidth,letheight);
  263.           XDrawString(rmystuff,lstbox.x+1,lstbox.y+i*letheight,
  264.             lst[i+k].name, min(strlen(lst[i+k].name),10));
  265.           if (lst[i+k].ftype) 
  266.             XDrawString(rmystuff,lstbox.x+1+letwidth*10,lstbox.y+i*letheight,"<dir>",5);
  267.         }
  268.         else
  269.         { XDrawImageString (mystuff, lstbox.x+1,lstbox.y
  270.             +i*letheight,strcat(strcpy(dum3,lst[i+k].name),"               "),10);
  271.           XDrawImageString(mystuff,lstbox.x+1+letwidth*10,lstbox.y+
  272.              i*letheight,(lst[i+k].ftype) ? "<dir>" : "     ",5);
  273.         }
  274.       for(; i<=rows; i++)
  275.       XDrawImageString (mydisplay, mywindow, mygc,lstbox.x+1,lstbox.y+i*letheight, 
  276.         "                       ", 15 );
  277.       XFillRectangles(mydisplay,mywindow,rmygc,&mvbox,1);
  278.       XDrawRectangles(mydisplay,mywindow,mygc,&mvbox,1);
  279.       XFillRectangle(mydisplay,mywindow,mygc,mvbox.x,mvbox.y+mvbox.height*
  280.         k/max((dirl+2),rows),mvbox.width,1+mvbox.height*rows/max(dirl+2,rows));
  281.     }
  282.     XNextEvent(mydisplay, &myevent);
  283.     switch(myevent.type) {
  284.     case ButtonRelease:
  285.       if (smooth) smooth=0;
  286.       break;
  287.     case MotionNotify:
  288.       if (smooth)  
  289.       { kold=k;
  290.         k=max((myevent.xmotion.y-mvbox.y)*max(dirl+2,rows),0)/mvbox.height;
  291.         k=max(min(dirl+2-rows,k),0); if (kold!=k) rdraw=1;
  292.       }
  293.       break;    
  294.     case MappingNotify:
  295.       XRefreshKeyboardMapping ( &myevent);
  296.       break;
  297.     case Expose:
  298.       if  (myevent.xexpose.count==0)
  299.         XGetWindowAttributes(mydisplay,mywindow, &sizeatt);
  300.       if (sizeatt.height!=myhint.height) 
  301.       { chrows=(sizeatt.height-myhint.height)/(letheight);
  302.         chrows=max(5-rows,chrows);
  303.         rows+=chrows; myhint.height+=chrows*letheight; init2();
  304.         k=max(min(dirl+2-rows,k),0);
  305.       }
  306.       XDrawRectangles(mystuff,&fnamebox,1); 
  307.       XDrawRectangles (mystuff,&lstbox,1);
  308.       XDrawRectangles (mystuff, &mvbox,1);
  309.       XDrawRectangles (mystuff, &upbox,1);
  310.       XDrawRectangles (mystuff, &downbox,1); 
  311.       XDrawRectangles (mystuff, &okbox,1); 
  312.       XDrawRectangles (mystuff, &cancelbox,1);  
  313.       XDrawImageString (mystuff,cancelbox.x+(cancelbox.width)/2
  314.         -letwidth*3,cancelbox.y+cancelbox.height/2+letheight/2,"CANCEL",6);
  315.       XDrawString(mystuff,10+fnamebox.x,(fnamebox.height+letheight)/2
  316.        +fnamebox.y-3,strcat(strcat(strcpy(dum3,prompt_string),inp_string),(getting)
  317.        ? "_" : " "),strlen(prompt_string)+strlen(inp_string)+1);
  318.       rdraw=1; 
  319.       break;
  320.     case KeyPress:
  321.       if (XLookupString(&myevent, text, 10, &mykey, 0)==1)
  322.       { if (!getting) 
  323.         { pstn = 0;
  324.           y =(fnamebox.height+letheight)/2+fnamebox.y-3;
  325.           x = 10+fnamebox.x + letwidth*strlen(prompt_string);
  326.           XDrawImageString(mystuff,x,y,"_                             ",30);
  327.           getting=1;
  328.         }
  329.         if((text[0] >= 32) && (text[0]!='/') && (text[0]!='{') && (text[0]!='}') 
  330.           && (text[0] <= 126) && pstn<30) 
  331.         { XDrawImageString(mystuff,x,y,text,1);
  332.           x += letwidth;
  333.           XDrawImageString(mystuff,x,y,"_",1);
  334.           inp_string[pstn] = text[0];
  335.           pstn++;
  336.         }
  337.         if(((text[0] == 8) || (text[0] == 127)) && (pstn>0)) 
  338.         { pstn--;
  339.           x -= letwidth;
  340.           XDrawImageString(mystuff,x,y,"_ ",2);
  341.         }
  342.         if (text[0]=='\r') 
  343.         { getting=0;
  344.           XDrawImageString(mystuff,x,y,"  ",2);  
  345.           inp_string[pstn] = 0;
  346.           if (pstn>0)
  347.           { Cleanlst(lst,dirl);
  348.             chgdir=0;
  349.             rdraw=1;
  350.             found=0;
  351.             message("");
  352.             for(i=dirl; i>=1; i--)
  353.               if (match(lst[i].name,inp_string) && (!lst[i].ftype)) 
  354.               { lst[i].chose=1; found=1; k=i-2;  k=max(min(dirl+2-rows,k),0);
  355.                 if (write_read) i=0; 
  356.               }
  357.             if ((!found) && (!write_read)) {message("Not found");}
  358.             if ((found) && (write_read)) {message("Note: Already Exists");}
  359.           }
  360.         }
  361.         inp_string[pstn] = 0;
  362.       }
  363.       break; 
  364.     case ButtonPress:
  365.       if (inbox(cancelbox,myevent)) done=2;
  366.       if (inbox(okbox,myevent)) 
  367.       if (chgdir) 
  368.       { XDefineCursor(mydisplay,mywindow,curs2); 
  369.  
  370.         flash(mystuff,okbox); 
  371.         strcat(dum2,"/");
  372.         strcat(dum2,inp);
  373.         flag=1; k=0; 
  374.         rdraw=1;
  375.         chgdir=0;
  376.       }
  377.       else done=1;
  378.       if (inbox(downbox,myevent)) { flash(mystuff,downbox); k++; }
  379.       if (inbox(upbox,myevent)) {flash(mystuff,upbox); k--; }
  380.       if (inbox(mvbox,myevent))
  381.       { k=(myevent.xbutton.y-mvbox.y)*max(dirl+2,rows)/mvbox.height; smooth=1;}
  382.       k=max(min(dirl+2-rows,k),0);
  383.       if (inbox(upbox,myevent) || inbox(downbox,myevent) || inbox(mvbox,myevent)) 
  384.         rdraw=1;
  385.       if (inbox(lstbox,myevent))
  386.       { ch=(myevent.xbutton.y-(lstbox.y+3))/letheight+1; 
  387.         if (ch+k>dirl) ch=0;
  388.         rdraw=1;
  389.         if (chgdir) { Cleanlst(lst,dirl); chgdir=0;}
  390.         lst[ch+k].chose=(!lst[ch+k].chose);
  391.         if ((ch>=1) && (ch<=rows) && ((lst[ch+k].ftype==1) || (write_read)))   
  392.         { strcpy(inp,lst[ch+k].name);
  393.           Cleanlst(lst,dirl);
  394.           lst[ch+k].chose=1;
  395.           if (lst[ch+k].ftype) chgdir=1;
  396.         }
  397.       }
  398.       break;
  399.     }
  400.   }
  401. /*
  402. TOBY
  403.   chfree(namesc,namesv);
  404. */
  405.   *namesc=0;
  406.   if (done==2) {*namesv=NULL; *dpath=NULL; }
  407.   else
  408.   { *namesv=(char **)malloc(dirl*sizeof(char *));
  409.     for(i=1; i<=dirl; i++)
  410.       if (lst[i].chose)
  411.       { 
  412.         *((*namesv)+(*namesc))=(char *)malloc(strlen(lst[i].name)+2);
  413.         strcpy(*((*namesv)+(*namesc)),lst[i].name);
  414.         (*namesc)++;
  415.       }
  416.   /*  if (dpath!=NULL) free(dpath); */
  417.     if ((*namesc)==0 && write_read==1 && strlen(inp_string)>0) 
  418.     {
  419.         *((*namesv)+(*namesc))=(char *)malloc(strlen(inp_string)+2);
  420.         strcpy(*((*namesv)+(*namesc)),inp_string);
  421.         (*namesc)++;
  422.     }
  423.       
  424.     *dpath=(char *)malloc(strlen(dum2)+2);
  425.     strcpy(*dpath,dum2);
  426.   }
  427.   XFreeGC (mydisplay,mygc); 
  428.   XDestroyWindow (mydisplay,mywindow);
  429. /*** TOBY
  430.   XCloseDisplay (mydisplay);
  431. ****/
  432.   return(*namesc);
  433. }
  434.  
  435.